﻿using Nasty.Core.Attributes;
using Nasty.Core.Session;
using Nasty.Core.SuperExtension;
using SqlSugar;
using System.Reflection;

namespace Nasty.Core.Entity
{
    public abstract class StandardEntity<T> : BaseEntity<T> where T : class, IBaseEntity, new()
    {
        [SugarColumn(ColumnName = "CreateTime", IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建时间")]
        public DateTime? CreateTime { get; set; }

        [SugarColumn(ColumnName = "CreateUser", IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建用户")]
        public string? CreateUser { get; set; }

        [SugarColumn(ColumnName = "CreateUserId", IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建用户Id")]
        public string? CreateUserId { get; set; }

        [SugarColumn(ColumnName = "CreateDept", IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建部门")]
        public string? CreateDept { get; set; }

        [SugarColumn(ColumnName = "CreateDeptId", IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建部门Id")]
        public string? CreateDeptId { get; set; }


        [SugarColumn(ColumnName = "UpdateTime", IsNullable = true, ColumnDescription = "修改时间")]
        public DateTime? UpdateTime { get; set; }

        [SugarColumn(ColumnName = "UpdateUser", IsNullable = true, ColumnDescription = "修改用户")]
        public string? UpdateUser { get; set; }

        [SugarColumn(ColumnName = "UpdateUserId", IsNullable = true, ColumnDescription = "修改用户Id")]
        public string? UpdateUserId { get; set; }

        [SugarColumn(ColumnName = "UpdateDept", IsNullable = true, ColumnDescription = "修改部门")]
        public string? UpdateDept { get; set; }

        [SugarColumn(ColumnName = "UpdateDeptId", IsNullable = true, ColumnDescription = "修改部门Id")]
        public string? UpdateDeptId { get; set; }


        public override void OnPreAdd()
        {
            if (string.IsNullOrEmpty(this.Id)) this.Id = SnowFlakeSingle.Instance.NextId().ToString();
            this.CreateTime = DateTime.Now;
            var info = AppSession.CurrentUser.Value;
            if (info != null)
            {
                this.CreateUser = info.Name;
                this.CreateUserId = info.Id;
                if (info.MainDepartment != null)
                {
                    this.CreateDept = info.MainDepartment.Id;
                    this.CreateDeptId = info.MainDepartment.Name;
                }
            }

            //校验属性
            VerifyProperty();

            base.OnPreAdd();
        }

        public override void OnPreUpdate()
        {
            this.UpdateTime = DateTime.Now;
            var info = AppSession.CurrentUser.Value;
            if (info != null)
            {
                this.UpdateUser = info.Name;
                this.UpdateUserId = info.Id;
                if (info.MainDepartment != null)
                {
                    this.UpdateDept = info.MainDepartment.Id;
                    this.UpdateDeptId = info.MainDepartment.Name;
                }
            }

            //校验属性
            VerifyProperty();

            base.OnPreUpdate();
        }

        public void VerifyProperty()
        {
            var tableName = this.GetTableName();
            var db = AppSession.CurrentDb.Value;

            //得到所有字段
            var properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var property in properties)
            {
                //检查是否有Required特性
                var attribute = property.GetCustomAttribute<NastyColumnAttribute>();
                //判断是否为空
                if (attribute == null) continue;
                //当启动重复查询时，默认也启用必填校验
                if (attribute.IsRepeat) attribute.Required = true;
                //获取值
                var value = property.GetValue(this);

                //校验必填
                if (attribute.Required)
                {
                    var isError = false;

                    if (value == null) isError = true;
                    if (!isError && value is string str && string.IsNullOrWhiteSpace(str)) isError = true;
                    if (!isError && value is global::System.Collections.IList list && list.Count == 0) isError = true;

                    if (isError)
                    {
                        var name = string.IsNullOrWhiteSpace(attribute.ColumnDescription) ? attribute.ColumnName : attribute.ColumnDescription;
                        throw new Exception($"{name}不能为空");
                    }
                }

                //校验重复
                if (attribute.IsRepeat)
                {
                    var links = (attribute.RepeatLink ?? string.Empty).Split(',').Where((t) => !string.IsNullOrWhiteSpace(t));
                    var dicts = new Dictionary<string, object>()
                    {
                        {attribute.ColumnName,value }
                    };


                    foreach (var link in links)
                    {
                        //得到对应属性的值
                        var linkValue = this.GetPropertyValue(link);
                        dicts.Add(link, linkValue);
                    }

                    var isAny = db.Queryable<T>().Where((t) => t.Id != this.Id).WhereColumns(dicts).Any();

                    if (isAny)
                    {
                        var name = string.IsNullOrWhiteSpace(attribute.ColumnDescription) ? attribute.ColumnName : attribute.ColumnDescription;
                        throw new Exception($"{name}重复");
                    }
                }
            }
        }

    }
}
